/*
 * @Author: xiguan
 * @Email: xiguan.teng@qq.com
 * @Version: 1.0
 * @Date: 2022-07-22 15:47:58
 * @LastEditTime: 2022-07-31 12:12:37
 */


#ifndef _UTILITYMY_H_
#define _UTILITYMY_H_

namespace MySTL{

    /**
     * @brief : [ swap ]
     * @param { T} &a
     * @param { T} &b
     */  
    template<class T>  
    void swap( T &a, T &b ){
        T temp = a;
        a = b;
        b = temp;
    }


    template<class T1, class T2>
    struct pair{
    
    public:
        typedef T1      first_type;
        typedef T2      second_type;

        T1 first;
        T2 second;
    
    public:
        pair() = default;

        template<class Other1, class Other2>
        pair( const pair<Other1, Other2> &pr );
        pair( const first_type &a, const second_type &b );

        pair &operator=( const pair &pr );
        
        void swap( pair &pr );
    
    public:
        template<class T1f, class T2f>
        friend bool operator==( const pair<T1f, T2f> &lhs, const pair<T1f, T2f> &rhs );
        template<class T1f, class T2f>
        friend bool operator!=( const pair<T1f, T2f> &lhs, const pair<T1f, T2f> &rhs );
        template<class T1f, class T2f>
        friend bool operator<( const pair<T1f, T2f> &lhs, const pair<T1f, T2f> &rhs );
        template<class T1f, class T2f>
        friend bool operator<=( const pair<T1f, T2f> &lhs, const pair<T1f, T2f> &rhs );
        template<class T1f, class T2f>
        friend bool operator>( const pair<T1f, T2f> &lhs, const pair<T1f, T2f> &rhs );
        template<class T1f, class T2f>
        friend bool operator>=( const pair<T1f, T2f> &lhs, const pair<T1f, T2f> &rhs );
        template <class T1f, class T2f>
		friend void swap( pair<T1f, T2f> &x, pair<T1f, T2f> &y);

    };


    template<class T1, class T2> 
    template<class Other1, class Other2> pair<T1, T2>::pair( const pair<Other1, Other2> &pr ) : first(pr.first), second(pr.second){

    }
    
    template<class T1, class T2>
    pair<T1, T2>::pair( const first_type &a, const second_type &b ) : first(a), second(b){

    }
    
    template<class T1, class T2>
    pair<T1, T2> &pair<T1, T2>::operator=( const pair &pr ){
        if( this != &pr ){
            first = pr.first;
            second = pr.second;;
        }
        return *this;
    }

    template<class T1, class T2>
    void pair<T1, T2>::swap( pair &pr ){
        MySTL::swap( first, pr.first );
        MySTL::swap( second, pr.second );
    }
    
    template<class T1f, class T2f>
    bool operator==( const pair<T1f, T2f> &lhs, const pair<T1f, T2f> &rhs ){
        return (lhs.first == rhs.first && lhs.second == rhs.second);
    }

    template<class T1f, class T2f>
    bool operator!=( const pair<T1f, T2f> &lhs, const pair<T1f, T2f> &rhs ){
        return !(lhs == rhs);
    }

    template<class T1f, class T2f>
    bool operator<( const pair<T1f, T2f> &lhs, const pair<T1f, T2f> &rhs ){
        return lhs.first < rhs.first || ( !(rhs.first < lhs.first) && lhs.second < rhs.second );
    }

    template<class T1f, class T2f>
    bool operator<=( const pair<T1f, T2f> &lhs, const pair<T1f, T2f> &rhs ){
        return !(rhs < lhs);
    }

    template<class T1f, class T2f>
    bool operator>( const pair<T1f, T2f> &lhs, const pair<T1f, T2f> &rhs ){
        return rhs < lhs;
    }

    template<class T1f, class T2f>
    bool operator>=( const pair<T1f, T2f> &lhs, const pair<T1f, T2f> &rhs ){
        return !(lhs < rhs);
    }

    template <class T1f, class T2f>
	void swap( pair<T1f, T2f> &x, pair<T1f, T2f> &y){
        x.swap( y );
    }

    template<class T1, class T2>
    pair<T1, T2> make_pair( const T1 &a, const T2 &b ){
        return pair<T1, T2>(a, b);
    }


}

#endif